home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / shllutil.lha / shellutils-1.8 / lib / getusershell.c < prev    next >
C/C++ Source or Header  |  1992-07-17  |  4KB  |  197 lines

  1. /* getusershell.c -- Return names of valid user shells.
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
  19.  
  20. #ifndef SHELLS_FILE
  21. /* File containing a list of nonrestricted shells, one per line. */
  22. #define SHELLS_FILE "/etc/shells"
  23. #endif
  24.  
  25. #include <stdio.h>
  26. #include <ctype.h>
  27.  
  28. #ifdef STDC_HEADERS
  29. #include <stdlib.h>
  30. #else
  31. char *malloc ();
  32. char *realloc ();
  33. #endif
  34.  
  35. static int readname ();
  36.  
  37. /* List of shells to use if the shells file is missing. */
  38. static char *default_shells[] =
  39. {
  40.   "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL
  41. };
  42.  
  43. /* Index of the next shell in `default_shells' to return.
  44.    0 means we are not using `default_shells'. */
  45. static int default_index = 0;
  46.  
  47. /* Input stream from the shells file. */
  48. static FILE *shellstream = NULL;
  49.  
  50. /* Line of input from the shells file. */
  51. static char *line = NULL;
  52.  
  53. /* Number of bytes allocated for `line'. */
  54. static int line_size = 0;
  55.  
  56. /* Return an entry from the shells file, ignoring comment lines.
  57.    Return NULL if there are no more entries.  */
  58.  
  59. char *
  60. getusershell ()
  61. {
  62.   if (default_index > 0)
  63.     {
  64.       if (default_shells[default_index])
  65.     /* Not at the end of the list yet.  */
  66.     return default_shells[default_index++];
  67.       return NULL;
  68.     }
  69.  
  70.   if (shellstream == NULL)
  71.     {
  72.       shellstream = fopen (SHELLS_FILE, "r");
  73.       if (shellstream == NULL)
  74.     {
  75.       /* No shells file.  Use the default list.  */
  76.       default_index = 1;
  77.       return default_shells[0];
  78.     }
  79.     }
  80.  
  81.   while (readname (&line, &line_size, shellstream))
  82.     {
  83.       if (*line != '#')
  84.     return line;
  85.     }
  86.   return NULL;            /* End of file. */
  87. }
  88.  
  89. /* Rewind the shells file. */
  90.  
  91. void
  92. setusershell ()
  93. {
  94.   default_index = 0;
  95.   if (shellstream == NULL)
  96.     shellstream = fopen (SHELLS_FILE, "r");
  97.   else
  98.     fseek (shellstream, 0L, 0);
  99. }
  100.  
  101. /* Close the shells file. */
  102.  
  103. void
  104. endusershell ()
  105. {
  106.   if (shellstream)
  107.     {
  108.       fclose (shellstream);
  109.       shellstream = NULL;
  110.     }
  111. }
  112.  
  113. /* Allocate N bytes of memory dynamically, with error checking.  */
  114.  
  115. static char *
  116. xmalloc (n)
  117.      unsigned n;
  118. {
  119.   char *p;
  120.  
  121.   p = malloc (n);
  122.   if (p == 0)
  123.     {
  124.       fprintf (stderr, "virtual memory exhausted\n");
  125.       exit (1);
  126.     }
  127.   return p;
  128. }
  129.  
  130. /* Reallocate space P to size N, with error checking.  */
  131.  
  132. static char *
  133. xrealloc (p, n)
  134.      char *p;
  135.      unsigned n;
  136. {
  137.   p = realloc (p, n);
  138.   if (p == 0)
  139.     {
  140.       fprintf (stderr, "virtual memory exhausted\n");
  141.       exit (1);
  142.     }
  143.   return p;
  144. }
  145.  
  146. /* Read a line from STREAM, removing any newline at the end.
  147.    Place the result in *NAME, which is malloc'd
  148.    and/or realloc'd as necessary and can start out NULL,
  149.    and whose size is passed and returned in *SIZE.
  150.  
  151.    Return the number of characters placed in *NAME
  152.    if some nonempty sequence was found, otherwise 0.  */
  153.  
  154. static int
  155. readname (name, size, stream)
  156.      char **name;
  157.      int *size;
  158.      FILE *stream;
  159. {
  160.   int c;
  161.   int name_index = 0;
  162.  
  163.   if (*name == NULL)
  164.     {
  165.       *size = 10;
  166.       *name = (char *) xmalloc (*size);
  167.     }
  168.  
  169.   /* Skip blank space.  */
  170.   while ((c = getc (stream)) != EOF && isspace (c))
  171.     /* Do nothing. */ ;
  172.   
  173.   while (c != EOF && !isspace (c))
  174.     {
  175.       (*name)[name_index++] = c;
  176.       while (name_index >= *size)
  177.     {
  178.       *size *= 2;
  179.       *name = (char *) xrealloc (*name, *size);
  180.     }
  181.       c = getc (stream);
  182.     }
  183.   (*name)[name_index] = '\0';
  184.   return name_index;
  185. }
  186.  
  187. #ifdef TEST
  188. main ()
  189. {
  190.   char *s;
  191.  
  192.   while (s = getusershell ())
  193.     puts (s);
  194.   exit (0);
  195. }
  196. #endif
  197.